package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 自定义切面，实现公共字段自动填充
 * @create 2023-08-08 21:01
 * @Description
 */
@Aspect
@Component
public class AutoFillAspect {
//切入点
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}

    /*
    前置通知
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        System.out.println("自动填充");
        //获取到拦截方法的对象
        //获取切面的方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //获取到拦截方法上的注解的值
        //根据方法签名获取到方法上的注解对象
        AutoFill annotation = method.getAnnotation(AutoFill.class);
        OperationType type = annotation.value();
        //获取到拦截方法的参数
        Object[] args = joinPoint.getArgs();
        if(args == null && args.length == 0){
            return;
        }
        Object entity = args[0];
        // 根据注解的值，调用对应的方法
        switch (type){
            case INSERT:
                //insert有四个属性
                System.out.println("插入");
                //获取拦截方法的实体类
                //赋值
                try {
                    entity.getClass()
                            .getDeclaredMethod("setCreateTime",java.time.LocalDateTime.class)
                            .invoke(entity,java.time.LocalDateTime.now());
                    entity.getClass()
                            .getDeclaredMethod("setUpdateTime",java.time.LocalDateTime.class)
                            .invoke(entity,java.time.LocalDateTime.now());
                    entity.getClass()
                            .getDeclaredMethod("setCreateUser",Long.class)
                            .invoke(entity, BaseContext.getCurrentId());
                    entity.getClass()
                            .getDeclaredMethod("setUpdateUser",Long.class)
                            .invoke(entity, BaseContext.getCurrentId());
                    break;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            case UPDATE:
                //update有两个属性
                System.out.println("更新");

                try {
                    entity.getClass()
                            .getDeclaredMethod("setUpdateTime",java.time.LocalDateTime.class)
                            .invoke(entity,java.time.LocalDateTime.now());

                    entity.getClass()
                            .getDeclaredMethod("setUpdateUser",Long.class)
                            .invoke(entity, BaseContext.getCurrentId());
                    break;
                } catch (Exception e) {
                    e.printStackTrace();
                }
        }
    }
}
